/*
*Copyright 2021-2023 NERCIS
*
*Licensed under the Apache License, Version 2.0 (the "License");
*you may not use this file except in compliance with the License.
*You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*Unless required by applicable law or agreed to in writing, software
*distributed under the License is distributed on an "AS IS" BASIS,
*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*See the License for the specific language governing permissions and
*limitations under the License.
*/

package cn.ac.nercis.pes.community.service.paste;

import cn.ac.nercis.pes.common.constant.evaluation.EvaluationModule;
import cn.ac.nercis.pes.common.constant.knowledge.AssetClassification;
import cn.ac.nercis.pes.common.constant.project.SystemState;
import cn.ac.nercis.pes.common.event.ProcessCallback;
import cn.ac.nercis.pes.model.dto.common.DataCopy;
import cn.ac.nercis.pes.model.dto.common.Result;
import cn.ac.nercis.pes.model.dto.evaluation.content.BusinessConditionDTO;
import cn.ac.nercis.pes.model.dto.evaluation.content.LastEvaluationDTO;
import cn.ac.nercis.pes.model.dto.evaluation.content.NetworkTopologyDTO;
import cn.ac.nercis.pes.model.dto.evaluation.content.ToolCheckPointDTO;
import cn.ac.nercis.pes.model.dto.evaluation.prepare.*;
import cn.ac.nercis.pes.repository.dal.evaluation.AssetRepository;
import cn.ac.nercis.pes.repository.mapper.standard.SystemExportMapper;
import cn.ac.nercis.pes.service.evaluation.*;
import cn.ac.nercis.pes.service.exception.ImportAssetFailException;
import cn.ac.nercis.pes.service.project.SystemEvaluationService;
import cn.ac.nercis.pes.service.project.SystemProcessService;
import cn.ac.nercis.pes.service.project.imported.SystemAssetImportService;
import cn.ac.nercis.pes.service.utils.FileManage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * 测评准备阶段相关数据粘贴服务类
 *
 * @author zpy
 * @version 1.0.0
 */
@Slf4j
@Service
public class PreparePasteService {

    private final SystemEvaluationService systemEvaluationService;
    private final SystemProcessService systemProcessService;
    private final EvaluationContentService evaluationContentService;
    private final EvaluationProcessService evaluationProcessService;
    private final SecurityDocumentService securityDocumentService;
    private final PersonnelService personnelService;
    private final PasswordServerService passwordServerService;
    private final SecurityThreatService securityThreatService;
    private final EvaluationToolsService evaluationToolsService;
    private final SystemAssetImportService systemAssetImportService;

    private final AssetRepository assetRepository;
    private ProcessCallback processCallback;


    @Autowired
    public PreparePasteService(SystemEvaluationService systemEvaluationService,
                               SystemProcessService systemProcessService,
                               EvaluationContentService evaluationContentService,
                               EvaluationProcessService evaluationProcessService,
                               SecurityDocumentService securityDocumentService,
                               PersonnelService personnelService,
                               PasswordServerService passwordServerService,
                               SecurityThreatService securityThreatService,
                               EvaluationToolsService evaluationToolsService,
                               SystemAssetImportService systemAssetImportService,
                               AssetRepository assetRepository) {
        this.systemEvaluationService = systemEvaluationService;
        this.systemProcessService = systemProcessService;
        this.evaluationContentService = evaluationContentService;
        this.evaluationProcessService = evaluationProcessService;
        this.securityDocumentService = securityDocumentService;
        this.personnelService = personnelService;
        this.passwordServerService = passwordServerService;
        this.securityThreatService = securityThreatService;
        this.evaluationToolsService = evaluationToolsService;
        this.systemAssetImportService = systemAssetImportService;
        this.assetRepository = assetRepository;
    }

    public Result<String> dataPaste(String systemId, DataCopy dataCopy){
        if(StringUtils.equals(systemId,dataCopy.getCopySystemId())){
            return Result.success();
        }
        var module = EvaluationModule.fromNameByPrepare(dataCopy.getName());
        return switch (module) {
            case EVALUATION_INF_SYSTEM -> evaluationInfoPaste(systemId, dataCopy.getCopySystemId());
            case EVALUATION_BASIS -> evaluationBasePaste(systemId, dataCopy.getCopySystemId());
            case COURSE -> evaluationCourse(systemId, dataCopy.getCopySystemId());
            case COURSE_PROCESS -> evaluationCourseProcess(systemId, dataCopy.getCopySystemId());
            case COURSE_MEMBER -> evaluationCourseMember(systemId, dataCopy.getCopySystemId());
            case BUSINESS -> evaluationBusiness(systemId, dataCopy.getCopySystemId());
            case NETWORK_TOPOLOGY -> evaluationNetWorkTopology(systemId, dataCopy.getCopySystemId());
            case PASSWORD_USE -> evaluationPasswordUse(systemId, dataCopy.getCopySystemId());
            case SYSTEM_ASSET -> evaluationSystemAsset(systemId, dataCopy.getCopySystemId());
            case ASSET_PHY_ENV -> evaluationPhyEnv(systemId, dataCopy.getCopySystemId());
            case ASSET_PHY_SECURITY -> evaluationPhySecurity(systemId, dataCopy.getCopySystemId());
            case ASSET_PWD_PRODUCT -> evaluationPwdProduct(systemId, dataCopy.getCopySystemId());
            case ASSET_SERVER_STORAGE -> evaluationServerStorage(systemId, dataCopy.getCopySystemId());
            case ASSET_NETWORK_SECURITY -> evaluationNetworkSecurity(systemId, dataCopy.getCopySystemId());
            case ASSET_DATABASE -> evaluationDatabase(systemId, dataCopy.getCopySystemId());
            case ASSET_KEY_BUSINESS -> evaluationKeyBusiness(systemId, dataCopy.getCopySystemId());
            case ASSET_KEY_DATA -> evaluationKeyData(systemId, dataCopy.getCopySystemId());
            case ASSET_COMMUNICATION_CHANNEL -> evaluationChannel(systemId, dataCopy.getCopySystemId());
            case ASSET_SECURITY_DOC -> evaluationSecurityDoc(systemId, dataCopy.getCopySystemId());
            case ASSET_PERSONNEL -> evaluationPersonnel(systemId, dataCopy.getCopySystemId());
            case PASSWORD_SERVICE -> evaluationPasswordService(systemId, dataCopy.getCopySystemId());
            case SECURITY_THREAT -> evaluationSecurityThreat(systemId, dataCopy.getCopySystemId());
            case LAST_EVALUATION -> evaluationLastEvaluation(systemId, dataCopy.getCopySystemId());
            case METHOD_TOOL -> evaluationMethodTool(systemId, dataCopy.getCopySystemId());
            case METHOD_TOOL_TOOLS -> evaluationTools(systemId, dataCopy.getCopySystemId());
            case METHOD_TOOL_POINT -> evaluationToolPoint(systemId, dataCopy.getCopySystemId());
            default -> Result.failed("不支持的数据复制操作！");
        };
    }

    private void evalProcessPaste(String systemId,String copySystemId,EvaluationModule module){
        var copyProcess = systemProcessService.findSystemProcess(copySystemId, SystemState.PREPARE)
                .stream()
                .filter(sp->StringUtils.equals(module.getName(),sp.getName()))
                .findFirst()
                .orElse(null);
        if(Objects.isNull(copyProcess)){
            return;
        }
        systemProcessService.setSystemProcess(systemId,module,copyProcess.getFinishState());
    }

    private Result<String> evaluationInfoPaste(String systemId,String copySystemId){
        var copyData = this.systemEvaluationService.getSystemEvaluation(copySystemId);
        var opResult = this.systemEvaluationService.save(systemId,copyData);
        if(opResult.isSuccess()){
            evalProcessPaste(systemId,copySystemId,EvaluationModule.EVALUATION_INF_SYSTEM);
            return opResult;
        }else{
            return Result.failed("粘贴失败！");
        }
    }

    private Result<String> evaluationBasePaste(String systemId,String copySystemId){
        var copyData = this.evaluationContentService.findEvaluationBasis(copySystemId);
        var opResult = this.evaluationContentService.saveEvaluationBasis(systemId,copyData);
        if(opResult.isSuccess()){
            evalProcessPaste(systemId,copySystemId,EvaluationModule.EVALUATION_BASIS);
            return opResult;
        }else{
            return Result.failed("粘贴失败！");
        }
    }

    private Result<String> evaluationCourse(String systemId,String copySystemId){
        processNotify(0.1,"测评过程粘贴中....");
        evaluationCourseProcess(systemId,copySystemId);
        processNotify(0.5,"测评项目组成员粘贴中....");
        evaluationCourseMember(systemId,copySystemId);
        processSuccess();
        return Result.success();
    }

    private Result<String> evaluationCourseProcess(String systemId,String copySystemId){
        var copyData = this.evaluationProcessService.getEvaluationStage(copySystemId);
        //复制的信息中系统ID变更为当前系统ID
        copyData.setSystemId(systemId);
        var opResult = this.evaluationProcessService.saveEvaluationState(copyData);
        if(opResult.isSuccess()){
            evalProcessPaste(systemId,copySystemId,EvaluationModule.COURSE_PROCESS);
            return opResult;
        }else{
            return Result.failed("粘贴失败！");
        }
    }

    private Result<String> evaluationCourseMember(String systemId,String copySystemId){
        var copyData = this.evaluationProcessService.findEvaluators(copySystemId);
        if(CollectionUtils.isEmpty(copyData)){
            return Result.success();
        }
        var currentData = this.evaluationProcessService.findEvaluators(systemId);
        List<EvaluatorDTO> modifyData = new ArrayList<>();
        for(var item : copyData){
           var source = currentData.stream()
                    .filter(st -> StringUtils.equals(st.getName(), item.getName()))
                    .findFirst().orElse(null);
           if(Objects.isNull(source)){
               item.setId("");
               item.setSystemId(systemId);
           }else{
               item.setId(source.getId());
               item.setSystemId(source.getSystemId());
           }
            modifyData.add(item);
        }
        var opResult = this.evaluationProcessService.batchSave(modifyData);
        if (opResult.isSuccess()) {
            evalProcessPaste(systemId, copySystemId, EvaluationModule.COURSE_MEMBER);
            return opResult;
        } else {
            return Result.failed("粘贴失败！");
        }
    }


    private Result<String> evaluationBusiness(String systemId, String copySystemId) {
        var copyData = this.evaluationContentService.findBusinessCondition(copySystemId);
        //复制的信息中系统ID变更为当前系统ID
        BusinessConditionDTO businessCondition = BusinessConditionDTO.builder()
                .content(StringUtils.trim(copyData.getContent()))
                .contentPicture(copyData.getContentPicture())
                .build();
        if (StringUtils.isNotBlank(businessCondition.getContentPicture())) {
            List<String> list = Arrays.asList(businessCondition.getContentPicture().split("\\|"));
            list.forEach(li -> {
                File file = FileUtils.getFile(FileManage.getBusinessContentDir(copySystemId), li);
                File distFile = FileUtils.getFile(FileManage.getBusinessContentDir(systemId), li);
                try {
                    FileManage.copyFile(file, distFile);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            });
        }

        var opResult = this.evaluationContentService.saveBusinessCondition(systemId, businessCondition);
        if (opResult.isSuccess()) {
            evalProcessPaste(systemId, copySystemId, EvaluationModule.BUSINESS);
            return opResult;
        } else {
            return Result.failed("粘贴失败！");
        }
    }

    private Result<String> evaluationNetWorkTopology(String systemId, String copySystemId) {
        var copyData = this.evaluationContentService.findNetworkTopology(copySystemId);
        //复制的信息中系统ID变更为当前系统ID
        NetworkTopologyDTO networkTopology = NetworkTopologyDTO.builder()
                .zoneSummary(copyData.getZoneSummary())
                .zoneIllustrate(copyData.getZoneIllustrate())
                .topologyPicture(copyData.getTopologyPicture())
                .build();
        if (StringUtils.isNotBlank(networkTopology.getTopologyPicture())) {
            File file = FileUtils.getFile(FileManage.getNetworkTopologyDir(copySystemId), networkTopology.getTopologyPicture());
            File saveFile = FileUtils.getFile(FileManage.getNetworkTopologyDir(systemId), networkTopology.getTopologyPicture());
            try {
                FileManage.copyFile(file, saveFile);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        var opResult = this.evaluationContentService.saveNetworkTopology(systemId, networkTopology);
        if (opResult.isSuccess()) {
            evalProcessPaste(systemId, copySystemId, EvaluationModule.NETWORK_TOPOLOGY);
            return opResult;
        } else {
            return Result.failed("粘贴失败！");
        }
    }

    private Result<String> evaluationPasswordUse(String systemId, String copySystemId) {
        var copyData = this.evaluationContentService.findPasswordCondition(copySystemId);
        var opResult = this.evaluationContentService.savePasswordCondition(systemId, copyData);
        if (opResult.isSuccess()) {
            evalProcessPaste(systemId, copySystemId, EvaluationModule.PASSWORD_USE);
            return opResult;
        } else {
            return Result.failed("粘贴失败！");
        }
    }

    private Result<String> evaluationSystemAsset(String systemId, String copySystemId) {
        var copyData = this.assetRepository.findAllBySystemId(copySystemId)
                .stream()
                .map(SystemExportMapper.INSTANCE::toStandardDTO)
                .toList();
        try {
            processNotify(0.1, "物理环境粘贴中....");
            systemAssetImportService.importAssetDataByPhyEnv(systemId, copyData, true);
            evalProcessPaste(systemId, copySystemId, EvaluationModule.ASSET_PHY_ENV);
            processNotify(0.2, "物理安防设施粘贴中....");
            systemAssetImportService.importAssetDataByPhySecurity(systemId, copyData, true);
            evalProcessPaste(systemId, copySystemId, EvaluationModule.ASSET_PHY_SECURITY);
            processNotify(0.3, "密码产品粘贴中....");
            systemAssetImportService.importAssetDataByPwdProduct(systemId, copyData, true);
            evalProcessPaste(systemId, copySystemId, EvaluationModule.ASSET_PWD_PRODUCT);
            processNotify(0.4, "服务器/存储设备粘贴中....");
            systemAssetImportService.importAssetDataByServerStorage(systemId, copyData, true);
            evalProcessPaste(systemId, copySystemId, EvaluationModule.ASSET_SERVER_STORAGE);
            processNotify(0.5, "网络及安全设备粘贴中....");
            systemAssetImportService.importAssetDataByNetworkSecurity(systemId, copyData, true);
            evalProcessPaste(systemId, copySystemId, EvaluationModule.ASSET_NETWORK_SECURITY);

            processNotify(0.6, "数据库管理系统粘贴中....");
            systemAssetImportService.importAssetDataByDatabase(systemId, copyData, true);
            evalProcessPaste(systemId, copySystemId, EvaluationModule.ASSET_DATABASE);
            processNotify(0.7, "关键业务应用粘贴中....");
            systemAssetImportService.importAssetDataByKeyBusiness(systemId, copyData, true);
            systemAssetImportService.importAssetDataBySubBusiness(systemId, copyData, true);
            evalProcessPaste(systemId, copySystemId, EvaluationModule.ASSET_KEY_BUSINESS);
            processNotify(0.7, "重要数据粘贴中....");
            systemAssetImportService.importAssetDataByKeyData(systemId, copyData, true);
            evalProcessPaste(systemId, copySystemId, EvaluationModule.ASSET_KEY_DATA);
            processNotify(0.8, "通信信道粘贴中....");
            systemAssetImportService.importAssetDataByCommunicationChannel(systemId, copyData, true);
            evalProcessPaste(systemId, copySystemId, EvaluationModule.ASSET_COMMUNICATION_CHANNEL);
            processNotify(0.8, "安全管理文档粘贴中....");
            evaluationSecurity(systemId, copySystemId);
            systemAssetImportService.importAssetDataByManageDoc(systemId, copyData, true);
            evalProcessPaste(systemId, copySystemId, EvaluationModule.ASSET_SECURITY_DOC);
            processNotify(0.9, "人员粘贴中....");
            evaluationPersonnel(systemId, copySystemId);
            processSuccess();
            return Result.success();
        }catch (ImportAssetFailException ex){
            log.error("粘贴资产数据失败：",ex);
            return Result.failed("粘贴资产数据失败！");
        }
    }

    private Result<String> evaluationPhyEnv(String systemId, String copySystemId) {
        var copyData = this.assetRepository.findAllBySystemIdAndClassId(copySystemId, AssetClassification.PHY_ENV.getId())
                .stream()
                .map(SystemExportMapper.INSTANCE::toStandardDTO)
                .toList();
        try{
            systemAssetImportService.importAssetDataByPhyEnv(systemId, copyData, true);
            evalProcessPaste(systemId, copySystemId, EvaluationModule.ASSET_PHY_ENV);
            return Result.success();
        }catch (ImportAssetFailException ex){
            log.error("粘贴物理环境资产数据失败：",ex);
            return Result.failed("粘贴物理环境资产数据失败！");
        }
    }

    private Result<String> evaluationPhySecurity(String systemId, String copySystemId) {
        var copyData = this.assetRepository.findAllBySystemIdAndClassId(copySystemId, AssetClassification.PHY_SECURITY.getId())
                .stream()
                .map(SystemExportMapper.INSTANCE::toStandardDTO)
                .toList();
        try{
            systemAssetImportService.importAssetDataByPhySecurity(systemId, copyData, true);
            evalProcessPaste(systemId, copySystemId, EvaluationModule.ASSET_PHY_SECURITY);
            return Result.success();
        }catch (ImportAssetFailException ex){
            log.error("粘贴物理安防设施资产数据失败：",ex);
            return Result.failed("粘贴物理安防设施资产数据失败！");
        }
    }

    private Result<String> evaluationPwdProduct(String systemId, String copySystemId) {
        var copyData = this.assetRepository.findAllBySystemIdAndClassId(copySystemId, AssetClassification.PWD_PRODUCT.getId())
                .stream()
                .map(SystemExportMapper.INSTANCE::toStandardDTO)
                .toList();
        try{
            systemAssetImportService.importAssetDataByPwdProduct(systemId, copyData, true);
            evalProcessPaste(systemId, copySystemId, EvaluationModule.ASSET_PWD_PRODUCT);
            return Result.success();
        }catch (ImportAssetFailException ex){
            log.error("粘贴密码产品资产数据失败：",ex);
            return Result.failed("粘贴密码产品资产数据失败！");
        }
    }

    private Result<String> evaluationServerStorage(String systemId, String copySystemId) {
        var copyData = this.assetRepository.findAllBySystemIdAndClassId(copySystemId, AssetClassification.SERVER_STORAGE.getId())
                .stream()
                .map(SystemExportMapper.INSTANCE::toStandardDTO)
                .toList();
        try {
            systemAssetImportService.importAssetDataByServerStorage(systemId, copyData, true);
            evalProcessPaste(systemId, copySystemId, EvaluationModule.ASSET_SERVER_STORAGE);
            return Result.success();
        } catch (ImportAssetFailException ex) {
            log.error("粘贴服务器/存储设备资产数据失败：", ex);
            return Result.failed("粘贴服务器/存储设备资产数据失败！");
        }
    }

    private Result<String> evaluationNetworkSecurity(String systemId, String copySystemId) {
        var copyData = this.assetRepository.findAllBySystemIdAndClassId(copySystemId, AssetClassification.NETWORK_SECURITY.getId())
                .stream()
                .map(SystemExportMapper.INSTANCE::toStandardDTO)
                .toList();
        try {
            systemAssetImportService.importAssetDataByNetworkSecurity(systemId, copyData, true);
            evalProcessPaste(systemId, copySystemId, EvaluationModule.ASSET_NETWORK_SECURITY);
            return Result.success();
        } catch (ImportAssetFailException ex) {
            log.error("粘贴网络及安全设备资产数据失败：", ex);
            return Result.failed("粘贴网络及安全设备资产数据失败！");
        }
    }

    private Result<String> evaluationDatabase(String systemId, String copySystemId) {
        var copyData = this.assetRepository.findAllBySystemIdAndClassId(copySystemId, AssetClassification.DATABASE.getId())
                .stream()
                .map(SystemExportMapper.INSTANCE::toStandardDTO)
                .toList();
        try {
            systemAssetImportService.importAssetDataByDatabase(systemId, copyData, true);
            evalProcessPaste(systemId, copySystemId, EvaluationModule.ASSET_DATABASE);
            return Result.success();
        } catch (ImportAssetFailException ex) {
            log.error("粘贴数据库管理系统资产数据失败：", ex);
            return Result.failed("粘贴数据库管理系统资产数据失败！");
        }
    }

    private Result<String> evaluationKeyBusiness(String systemId, String copySystemId) {
        var copyData = this.assetRepository.findAllBySystemIdAndClassId(copySystemId, AssetClassification.KEY_BUSINESS.getId())
                .stream()
                .map(SystemExportMapper.INSTANCE::toStandardDTO)
                .toList();
        var copyData2 = this.assetRepository.findAllBySystemIdAndClassId(copySystemId, AssetClassification.SUB_BUSINESS.getId())
                .stream()
                .map(SystemExportMapper.INSTANCE::toStandardDTO)
                .toList();
        try {
            systemAssetImportService.importAssetDataByKeyBusiness(systemId, copyData, true);
            systemAssetImportService.importAssetDataBySubBusiness(systemId, copyData2, true);
            evalProcessPaste(systemId, copySystemId, EvaluationModule.ASSET_KEY_BUSINESS);
            return Result.success();
        } catch (ImportAssetFailException ex) {
            log.error("粘贴关键业务应用资产数据失败：", ex);
            return Result.failed("粘贴关键业务应用资产数据失败！");
        }
    }


    private Result<String> evaluationKeyData(String systemId, String copySystemId) {
        var copyData = this.assetRepository.findAllBySystemIdAndClassId(copySystemId, AssetClassification.KEY_DATA.getId())
                .stream()
                .map(SystemExportMapper.INSTANCE::toStandardDTO)
                .toList();
        try {
            systemAssetImportService.importAssetDataByKeyData(systemId, copyData, true);
            evalProcessPaste(systemId, copySystemId, EvaluationModule.ASSET_KEY_DATA);
            return Result.success();
        } catch (ImportAssetFailException ex) {
            log.error("粘贴重要数据资产数据失败：", ex);
            return Result.failed("粘贴重要数据资产数据失败！");
        }
    }

    private Result<String> evaluationChannel(String systemId, String copySystemId) {
        var copyData = this.assetRepository.findAllBySystemIdAndClassId(copySystemId, AssetClassification.COMMUNICATION_CHANNEL.getId())
                .stream()
                .map(SystemExportMapper.INSTANCE::toStandardDTO)
                .toList();
        try {
            systemAssetImportService.importAssetDataByCommunicationChannel(systemId, copyData, true);
            evalProcessPaste(systemId, copySystemId, EvaluationModule.ASSET_COMMUNICATION_CHANNEL);
            return Result.success();
        } catch (ImportAssetFailException ex) {
            log.error("粘贴通信信道资产数据失败：", ex);
            return Result.failed("粘贴通信信道资产数据失败！");
        }
    }

    private Result<String> evaluationSecurityDoc(String systemId, String copySystemId) {
        var copyData = this.assetRepository.findAllBySystemIdAndClassId(copySystemId, AssetClassification.MANAGE_DOC.getId())
                .stream()
                .map(SystemExportMapper.INSTANCE::toStandardDTO)
                .toList();
        try {
            evaluationSecurity(systemId, copySystemId);
            systemAssetImportService.importAssetDataByManageDoc(systemId, copyData, true);
            evalProcessPaste(systemId, copySystemId, EvaluationModule.ASSET_SECURITY_DOC);
            return Result.success();
        } catch (ImportAssetFailException ex) {
            log.error("粘贴安全管理文档资产数据失败：", ex);
            return Result.failed("粘贴安全管理文档资产数据失败！");
        }
    }

    private Result<String> evaluationSecurity(String systemId, String copySystemId) {
        var copyData = this.securityDocumentService.findSecurityDocument(copySystemId);
        if (CollectionUtils.isEmpty(copyData)) {
            return Result.success();
        }
        var currentData = this.securityDocumentService.findSecurityDocument(systemId);
        List<SecurityDocumentDTO> modifyData = new ArrayList<>();
        for (var item : copyData) {
            var source = currentData.stream()
                    .filter(st -> StringUtils.equals(st.getName(), item.getName()))
                    .findFirst().orElse(null);
            if (Objects.isNull(source)) {
                item.setId("");
                item.setSystemId(systemId);
            } else {
                item.setId(source.getId());
                item.setSystemId(source.getSystemId());
            }
            modifyData.add(item);
        }
        var opResult = this.securityDocumentService.batchSaveSecurityDocument(modifyData);
        if (opResult.isSuccess()) {
            return opResult;
        } else {
            return Result.failed("粘贴失败！");
        }
    }

    private Result<String> evaluationPersonnel(String systemId, String copySystemId) {
        var copyData = this.personnelService.findPersonnel(copySystemId);
        if (CollectionUtils.isEmpty(copyData)) {
            return Result.success();
        }
        var currentData = this.personnelService.findPersonnel(systemId);
        List<PersonnelDTO> modifyData = new ArrayList<>();
        for (var item : copyData) {
            var source = currentData.stream()
                    .filter(st -> StringUtils.equals(st.getName(), item.getName()))
                    .findFirst().orElse(null);
            if (Objects.isNull(source)) {
                item.setId("");
                item.setSystemId(systemId);
            } else {
                item.setId(source.getId());
                item.setSystemId(source.getSystemId());
            }
            modifyData.add(item);
        }
        var opResult = this.personnelService.batchSavePersonnel(modifyData);
        if (opResult.isSuccess()) {
            evalProcessPaste(systemId, copySystemId, EvaluationModule.ASSET_PERSONNEL);
            return opResult;
        } else {
            return Result.failed("粘贴失败！");
        }
    }

    private Result<String> evaluationPasswordService(String systemId, String copySystemId) {
        var copyData = this.passwordServerService.findPasswordServer(copySystemId);
        if (CollectionUtils.isEmpty(copyData)) {
            return Result.success();
        }
        var currentData = this.passwordServerService.findPasswordServer(systemId);
        List<PasswordServerDTO> modifyData = new ArrayList<>();
        for (var item : copyData) {
            var source = currentData.stream()
                    .filter(st -> StringUtils.equals(st.getName(), item.getName()))
                    .findFirst().orElse(null);
            if (Objects.isNull(source)) {
                item.setId("");
                item.setSystemId(systemId);
            } else {
                item.setId(source.getId());
                item.setSystemId(source.getSystemId());
            }
            modifyData.add(item);
        }
        var opResult = this.passwordServerService.batchSavePasswordServer(modifyData);
        if (opResult.isSuccess()) {
            evalProcessPaste(systemId, copySystemId, EvaluationModule.PASSWORD_SERVICE);
            return opResult;
        } else {
            return Result.failed("粘贴失败！");
        }
    }


    private Result<String> evaluationSecurityThreat(String systemId, String copySystemId) {
        var copyData = this.securityThreatService.findSecurityThreat(copySystemId);
        if (CollectionUtils.isEmpty(copyData)) {
            return Result.success();
        }
        var currentData = this.securityThreatService.findSecurityThreat(systemId);
        List<SecurityThreatDTO> modifyData = new ArrayList<>();
        for (var item : copyData) {
            var source = currentData.stream()
                    .filter(st -> StringUtils.equals(st.getCode(), item.getCode()))
                    .findFirst().orElse(null);
            if (Objects.isNull(source)) {
                item.setId("");
                item.setSystemId(systemId);
            } else {
                item.setId(source.getId());
                item.setSystemId(source.getSystemId());
            }
            modifyData.add(item);
        }
        var opResult = this.securityThreatService.batchSaveSecurityThreat(modifyData);
        if (opResult.isSuccess()) {
            evalProcessPaste(systemId, copySystemId, EvaluationModule.SECURITY_THREAT);
            return opResult;
        } else {
            return Result.failed("粘贴失败！");
        }
    }

    private Result<String> evaluationLastEvaluation(String systemId, String copySystemId) {
        var copyData = this.evaluationContentService.findLastEvaluation(copySystemId);
        if (Objects.isNull(copyData)) {
            return Result.success();
        }
        int count = copyData.getCount();
        LastEvaluationDTO lastEvaluation = LastEvaluationDTO.builder()
                .count(count)
                .notFirst(count > 1)
                .build();
        if (lastEvaluation.getNotFirst()) {
            lastEvaluation.setLastDate(copyData.getLastDate());
            lastEvaluation.setConclusion(copyData.getConclusion());
            lastEvaluation.setUnit(copyData.getUnit());
            lastEvaluation.setScore(copyData.getScore());
        }
        var opResult = this.evaluationContentService.saveLastEvaluation(systemId, lastEvaluation);
        if (opResult.isSuccess()) {
            evalProcessPaste(systemId, copySystemId, EvaluationModule.LAST_EVALUATION);
            return opResult;
        } else {
            return Result.failed("粘贴失败！");
        }
    }

    private Result<String> evaluationMethodTool(String systemId, String copySystemId) {
        processNotify(0.1, "测评工具粘贴中....");
        evaluationTools(systemId, copySystemId);
        processNotify(0.5, "测评工具检查点粘贴中....");
        evaluationToolPoint(systemId, copySystemId);
        processSuccess();
        return Result.success();
    }

    private Result<String> evaluationTools(String systemId, String copySystemId) {
        var copyData = this.evaluationToolsService.findEvaluationTools(copySystemId);
        if (CollectionUtils.isEmpty(copyData)) {
            return Result.success();
        }
        var currentData = this.evaluationToolsService.findEvaluationTools(systemId);
        List<EvaluationToolsDTO> modifyData = new ArrayList<>();
        for (var item : copyData) {
            var source = currentData.stream()
                    .filter(st -> StringUtils.equals(st.getName(), item.getName()))
                    .findFirst().orElse(null);
            if (Objects.isNull(source)) {
                item.setId("");
                item.setSystemId(systemId);
            } else {
                item.setId(source.getId());
                item.setSystemId(source.getSystemId());
            }
            modifyData.add(item);
        }
        var opResult = this.evaluationToolsService.batchSaveEvaluationTools(modifyData);
        if (opResult.isSuccess()) {
            evalProcessPaste(systemId, copySystemId, EvaluationModule.METHOD_TOOL_TOOLS);
            return opResult;
        } else {
            return Result.failed("粘贴失败！");
        }
    }

    private Result<String> evaluationToolPoint(String systemId, String copySystemId) {
        var copyData = this.evaluationContentService.findToolCheckPoint(copySystemId);
        //复制的信息中系统ID变更为当前系统ID
        ToolCheckPointDTO checkPoint = ToolCheckPointDTO.builder()
                .desc(copyData.getDesc())
                .checkPointPicture(copyData.getCheckPointPicture())
                .build();
        if (StringUtils.isNotBlank(checkPoint.getCheckPointPicture())) {
            File file = FileUtils.getFile(FileManage.getCheckPointDir(copySystemId), checkPoint.getCheckPointPicture());
            File saveFile = FileUtils.getFile(FileManage.getCheckPointDir(systemId), checkPoint.getCheckPointPicture());
            try {
                FileManage.copyFile(file, saveFile);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        var opResult = this.evaluationContentService.saveToolCheckPoint(systemId, checkPoint);
        if (opResult.isSuccess()) {
            evalProcessPaste(systemId, copySystemId, EvaluationModule.METHOD_TOOL_POINT);
            return opResult;
        } else {
            return Result.failed("粘贴失败！");
        }
    }

    /**
     * 设置接收进度提示的回调方法
     *
     * @param callback 回调方法接口实现
     */
    public void setProcessCallback(ProcessCallback callback) {
        this.processCallback = callback;
    }

    private void processNotify(double value, String tip) {
        if (Objects.nonNull(processCallback)) {
            processCallback.process(value, tip);
        }
    }

    private void processSuccess() {
        if (Objects.nonNull(processCallback)) {
            processCallback.process(1, "");
        }
    }
}